package com.liveinstars.im.core.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.liveinstars.api.dto.BatchImGetUserReq;
import com.liveinstars.api.dto.ImGetUserInfo;
import com.liveinstars.api.facade.ImUserCentreApi;
import com.liveinstars.im.common.dto.ReportDTO;
import com.liveinstars.im.domain.dao.model.ChatGroup;
import com.liveinstars.im.domain.dao.model.ChatGroupMember;
import com.liveinstars.im.domain.dao.model.MessageGroup;
import com.liveinstars.im.domain.dao.model.Report;
import com.liveinstars.im.domain.manager.ChatGroupManager;
import com.liveinstars.im.domain.manager.ChatGroupMemberManager;
import com.liveinstars.im.domain.manager.MessageGroupManager;
import com.liveinstars.im.domain.manager.ReportManager;
import com.liveinstars.api.im.query.ChatGroupQuery;
import com.liveinstars.api.im.query.ReportQuery;
import com.liveinstars.api.im.vo.ChatGroupMsgReportRecordVO;
import com.liveinstars.api.im.vo.ChatGroupMsgReportVO;
import com.onepiece.cache.service.CacheService;
import com.liveinstars.im.common.enums.ReportStatusEnum;
import com.liveinstars.im.constant.ServerConstant;
import com.liveinstars.im.core.service.ReportService;
import com.onepiece.shipelves.common.Result;
import com.onepiece.shipelves.common.constant.Constant;
import com.onepiece.shipelves.common.utils.CacheUtil;
import com.onepiece.shipelves.common.vo.Page;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author: zhouze
 * @date: 2020/3/5
 */
@Service("reportService")
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportManager reportManager;

    @Autowired
    private ChatGroupManager chatGroupManager;

    @Autowired
    private ChatGroupMemberManager chatGroupMemberManager;

    @Autowired
    private ImUserCentreApi imUserCentreApi;

    @Autowired
    private MessageGroupManager messageGroupManager;

    @Autowired
    CacheService cache;


    @Override
    public void reportChatGroupMsg(ChatGroupMsgReportVO vo) {

        MessageGroup msg = messageGroupManager.getById(vo.getChatGroupId(), vo.getMsgId());
        Report report = new Report();
        report.setFromId(vo.getChatGroupId());
        report.setType(vo.getType());
        report.setReportContent(msg.getContent());
        report.setReportUserId(vo.getReportUserId());
        report.setReportedUserId(msg.getFromId());
        report.setSourceId(msg.getId());
        report.setSourceType(ServerConstant.UCG_MSG_REPORT);
        report.setState(Constant.STATE_VALID);
        report.setStatus(ReportStatusEnum.UN_DO.getValue());
        reportManager.add(report);
    }

    @Override
    public Page<ChatGroupMsgReportRecordVO> pageByQuery(ReportQuery query) {
        List<ChatGroupMsgReportRecordVO> list = Lists.newArrayList();
        IPage<Report> iPage = reportManager.pageByQuery(query);
        List<Report> records = iPage.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            Set<Long> userIdList = Sets.newHashSet();
            Set<Long> chatGroupIdList = Sets.newHashSet();
            List<ReportDTO> dtoList = Lists.newArrayList();
            for (Report report : records) {
                userIdList.add(report.getReportedUserId());
                userIdList.add(report.getReportUserId());
                chatGroupIdList.add(report.getFromId());
                dtoList.add(new ReportDTO(report));
            }
            BatchImGetUserReq batchImGetUserReq = new BatchImGetUserReq();
            batchImGetUserReq.setUids(new ArrayList<>(userIdList));
            Result<List<ImGetUserInfo>> listResult = imUserCentreApi.batchImGetUserInfo(batchImGetUserReq);
            Map<Long, String> userNameMap = Maps.newHashMap();
            if (listResult.getCode().equals(Result.SUCCESS)) {
                listResult.getData().forEach(user -> userNameMap.put(user.getUid(), user.getUserName()));
            }
            ChatGroupQuery chatGroupQuery = new ChatGroupQuery();
            chatGroupQuery.setIdList(new ArrayList<>(chatGroupIdList));
            List<ChatGroup> chatGroupList = chatGroupManager.listByQuery(chatGroupQuery);
            Map<Long, String> chatNameMap = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(chatGroupList)) {
                chatGroupList.forEach(chatGroup -> chatNameMap.put(chatGroup.getId(), chatGroup.getName()));
            }
            list = dtoList.stream().map(dto -> {
                if (userNameMap.containsKey(dto.getReport().getReportedUserId())) {
                    dto.setReportedUserName(userNameMap.get(dto.getReport().getReportedUserId()));
                }
                if (userNameMap.containsKey(dto.getReport().getReportUserId())) {
                    dto.setReportUserName(userNameMap.get(dto.getReport().getReportUserId()));
                }
                if (chatNameMap.containsKey(dto.getReport().getFromId())) {
                    dto.setChatGroupName(chatNameMap.get(dto.getReport().getFromId()));
                }
                ChatGroupMsgReportRecordVO chatGroupMsgReportRecordVO = dto.transTo();
                return chatGroupMsgReportRecordVO;
            }).collect(Collectors.toList());
        }
        Page<ChatGroupMsgReportRecordVO> page = new Page<>(list,
                Long.valueOf(iPage.getCurrent()).intValue(),
                Long.valueOf(iPage.getSize()).intValue(),
                Long.valueOf(iPage.getTotal()).intValue());
        return page;
    }

    @Override
    public void reportHandle(Long id, Integer status) {
        switch (ReportStatusEnum.valueOf(status)) {
            case ACCEPT:
                Report report = reportManager.getById(id);
                messageGroupManager.deleteByChatGroupIdAndMsgId(report.getFromId(), id);
                List<ChatGroupMember> memberList = chatGroupMemberManager.listMemberByChatGroupId(report.getFromId());
                for (ChatGroupMember member : memberList) {
                    removeUnReadUCGMsg(member.getUserId(), id);
                }
                reportManager.updateStatusById(id, ReportStatusEnum.ACCEPT.getValue());
                break;
            case REFUSE:
                reportManager.updateStatusById(id, ReportStatusEnum.REFUSE.getValue());
                break;
            default:
                break;
        }
    }

    public void removeUnReadUCGMsg(Long userId, Long msgId) {
        cache.zremrangebyscore(CacheUtil.getIMUserMessageList(userId), msgId, msgId);
    }
}
